<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    body,
    p {
        margin: 0;
        padding: 0;
    }

    .red {
        color: red;
    }

    .green {
        color: green;
    }
</style>

<body>
    <div id="app">
    </div>
</body>
<script>
    /**
     * 渲染摸快
     */
    function h(tag, props, children) {
        return {
            tag,
            props,
            children
        }
    }
    // 挂载函数
    function mount(vnode, container) {
        // 创建vnode.tag节点
        const el = vnode.el = document.createElement(vnode.tag);
        /**
         * 只考虑属性的添加
         */
        // props
        if (vnode.props) {
            for (const key in vnode.props) {
                const value = vnode.props[key];
                // 向节点添加属性
                el.setAttribute(key, value);
            }
        }
        // children
        if (vnode.children) {
            if (typeof vnode.children === 'string') {
                // 当子节点是string时，直接挂载
                el.textContent = vnode.children;
            } else {
                vnode.children.forEach(child => {
                    mount(child, el)
                });
            }
        }
        // 将节点插入容器中
        container.appendChild(el)
    }
    const vdom = h('div', {
        class: 'red'
    }, [h('span', null, 'hello')])

    mount(vdom, document.getElementById('app'))

    // 更新节点
    function patch(n1, n2) {
        if (n1.tag == n2.tag) {
            const el = n2.el = n1.el;
            const oldProps = n1.props || {};
            const newProps = n2.props || {};
            console.log(oldProps, newProps)
            // props
            for (const key in newProps) {
                const oldValue = oldProps[key];
                const newValue = newProps[key];
                if (newValue !== oldValue) {
                    el.setAttribute(key, newValue)
                }
            }

            // 旧的el中的props的属性没有了
            for (const key in oldProps) {
                if (!(key in newProps)) {
                    el.removeAttribute(key)
                }
            }
            // children
            const oldChildren = n1.children;
            const newChildren = n2.children;
            // 新节点是字符串
            if (typeof newChildren === 'string') {
                // 老节点是字符串
                if (typeof oldChildren === 'string') {
                    if (newChildren !== oldChildren) {
                        el.textContent = newChildren
                    }
                } else {
                    el.textContent = newChildren
                }
            } else {
                // 老节点是字符串
                if (typeof oldChildren === 'string') {
                    // 清空el节点下的元素
                    el.innerHTML = '';
                    // 添加新节点
                    newChildren.forEach(child => {
                        mount(child, el)
                    })
                } else {

                    console.log(oldChildren, newChildren)
                    // oldChildren、newChildren都是数组
                    const commonLength = Math.min(oldChildren.length, newChildren.length);
                    for (let i = 0; i < commonLength; i++) {
                        patch(oldChildren[i], newChildren[i])
                    }
                    if (newChildren.length > oldChildren.length) {
                        newChildren.slice(oldChildren.length).forEach(child => {
                            mount(child, el)
                        })
                    } else if (newChildren.length < oldChildren.length) {
                        oldChildren.slice(newChildren.length).forEach(child => {
                            el.removeAttribute(child.el)
                        })
                    }
                }
            }

        } else {
            // 替换
        }
    }

    const newvdom = h('div', {
        class: 'green'
    }, [h('span', null, [h('span', null, 'hello wolrd!')])])
    patch(vdom, newvdom)
    /** 响应模块 */
    
    /** 编译模块 */
</script>

</html>